package donnees;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FabriqueClient {
	public static FabriqueClient fc=null;
	private Map<Integer,Client> cache;
	Connection dbCon;
	PreparedStatement creer;
	PreparedStatement rechercherClient;
	PreparedStatement rechercherLesIdCommande;
	PreparedStatement recupererDernierID;
	PreparedStatement updater;
	
	public static FabriqueClient getInstance() throws SQLException{
		if(fc==null){
			fc=new FabriqueClient();
		}
		return fc;
	}
	private FabriqueClient() throws SQLException{
		this.cache=new HashMap<Integer,Client>();	
		this.initConnection();
	}
	public void initConnection() throws SQLException{
		this.dbCon=DB.getInstance().getConnection();
		this.creer=dbCon.prepareStatement("INSERT INTO client(idclient,nom,prenom,numero,rue,ville,cp) VALUES(NEXT VALUE FOR client_seq,?,?,?,?,?,?)");
		this.rechercherClient=dbCon.prepareStatement("SELECT nom,prenom,numero,rue,ville,cp FROM client WHERE idclient=?");
		this.rechercherLesIdCommande=dbCon.prepareStatement("SELECT idcommande FROM commande WHERE client_idclient=?");
		this.updater=dbCon.prepareStatement("UPDATE client SET nom=?, prenom=?, numero=?, rue=?, ville=?, cp=? WHERE idclient=?");
				
		// IDENTITY uniquement pour des colonnes identity et non les sequence
		// Pas non plus de fonction pour récupérer dernière valeur d'une sqce dans hsqldb ...
		//this.recupererDernierID = dbCon.prepareStatement("CALL IDENTITY()");
		
		this.recupererDernierID = dbCon.prepareStatement("SELECT max(idclient) FROM client");
		
	}
	
	
	public Client creer(String nom, String prenom,
			String numero, String rue, String ville, String cp) throws SQLException{
		//tester les données
		boolean flag=true;
		if(nom==null || nom.equals("") || nom.length()>40) flag=false;
		if(prenom==null || prenom.equals("") || prenom.length()>40) flag=false;
		if(rue==null || rue.equals("") || rue.length()>80) flag=false;
		if(ville==null || ville.equals("") || ville.length()>40) flag=false;
		if(cp==null || cp.equals("") || cp.length()>5) flag=false;
		//insérer le nouveau client
		if(flag){
			creer.clearParameters();
			creer.setString(1, nom);
			creer.setString(2, prenom);
			creer.setString(3, numero);
			creer.setString(4, rue);
			creer.setString(5, ville);
			creer.setString(6, cp);
			creer.executeUpdate();
			//récupérer son id et créer un objet Client à retourner
			ResultSet retour=recupererDernierID.executeQuery();
			retour.next();
			Client leClient=new Client(retour.getInt(1),nom,prenom,numero,rue,ville,cp,null);
			cache.put(retour.getInt(1), leClient);
			return leClient;
		}
		else{
			return null;
		}
		
	}
	
	
	public Client rechercher(Integer idClient) throws SQLException{
		if(cache.containsKey(idClient)){
			return cache.get(idClient);
		}
		else{
			rechercherClient.clearParameters();
			rechercherClient.setInt(1, idClient);
			ResultSet retour=rechercherClient.executeQuery();
			if(retour.next()){
				Client leClient=new Client(idClient,retour.getString(1),retour.getString(2),retour.getString(3),retour.getString(4),retour.getString(5),retour.getString(6),this.getLesIdCommandes(idClient));
				cache.put(idClient, leClient);
				return leClient;
			}
			return null;
		}
	}
	
	
	public void flushCache(){
		this.cache.clear();
	}
	
	public void deleteFromCache(Integer idClient) {
		this.cache.remove(idClient);
	}
	
	public List<Integer> getLesIdCommandes(Integer idClient) throws SQLException{
		List<Integer> lesId=new ArrayList<Integer>();
		rechercherLesIdCommande.setInt(1, idClient);
		ResultSet retour=rechercherLesIdCommande.executeQuery();
		while(retour.next()){
			lesId.add(retour.getInt(1));
		}
		return lesId;
	
	}
	
	
	public Client update(Integer idclient, String nom, String prenom, int numero,
			String adresse, String ville, String codepostal) throws SQLException {
		boolean flag=true;
		Client c = null;
		if(nom==null || nom.equals("") || nom.length()>40) flag=false;
		if(prenom==null || prenom.equals("") || prenom.length()>40) flag=false;
		if(adresse==null || adresse.equals("") || adresse.length()>80) flag=false;
		if(ville==null || ville.equals("") || ville.length()>40) flag=false;
		if(codepostal==null || codepostal.equals("") || codepostal.length()>5) flag=false;
		//insérer le nouveau client
		if(flag){			
			updater.clearParameters();
			updater.setString(1, nom);
			updater.setString(2, prenom);
			updater.setInt(3, numero);
			updater.setString(4, adresse);
			updater.setString(5, ville);
			updater.setString(6, codepostal);
			updater.setInt(7, idclient);
			updater.executeUpdate();
					
			// update cache
			deleteFromCache(idclient);
			c = rechercher(idclient);
			cache.put(idclient, c);
			
		}
		return c;
	}
}
